/*
 * Copyright (C) 2010 TopCoder Inc., All Rights Reserved.
 */
package com.hercules.android.receiver;

import java.util.Date;

import com.hercules.android.receiver.entities.ApplicationConnectionData;
import com.hercules.android.receiver.entities.XREApplicationData;

/**
 * <p>
 * This class contains the common methods used by the application.
 * </p>
 * 
 * @author TCSASSEMBER
 * @version 1.0
 */
public class ReceiverUtil {
    /**
     * Convert matrix from XRE representation to Android representation.
     * 
     * @param matrix
     *            the matrix in XRE representation
     * @return the matrix in Android representation
     */
    public static float[] getAndroidMatrix(Double[] matrix) {
        float[] newMatrix = new float[9];
        newMatrix[0] = matrix[0].floatValue();
        newMatrix[1] = matrix[4].floatValue();
        newMatrix[2] = matrix[12].floatValue();
        newMatrix[3] = matrix[1].floatValue();
        newMatrix[4] = matrix[5].floatValue();
        newMatrix[5] = matrix[13].floatValue();
        newMatrix[6] = matrix[3].floatValue();
        newMatrix[7] = matrix[7].floatValue();
        newMatrix[8] = matrix[15].floatValue();
        return newMatrix;
    }

    /**
     * Checks whether a string is null or empty.
     * 
     * @param str
     *            the string to check
     * @return true if the string is null or empty, false otherwise
     */
    public static boolean isEmpty(String str) {
        return str == null || str.trim().length() == 0;
    }

    /**
     * Checks whether an object is null.
     * 
     * @param name
     *            the name of the object
     * @param value
     *            the object to check
     * @throws IllegalArgumentException
     *             if the object is null
     */
    public static void checkNull(String name, Object value) {
        if (value == null) {
            throw new IllegalArgumentException("Parameter [" + name + "] can't be null.");
        }
    }

    /**
     * Checks whether a string is null or empty.
     * 
     * @param name
     *            the name of the string
     * @param value
     *            the string to check
     * @throws IllegalArgumentException
     *             if the string is null or empty
     */
    public static void checkString(String name, String value) {
        checkNull(name, value);
        if (isEmpty(value)) {
            throw new IllegalArgumentException("Parameter [" + name + "] can't be empty.");
        }
    }

    /**
     * Gets the content of onConnect event.
     * 
     * @param receiver
     *            the <code>Receiver</code> instance
     * @param recoonect
     *            a flag indicates whether to reconenct to XRE server
     * @return the content of onConnect event
     */
    public static String getConnectionEvent(Receiver receiver) {
        boolean reconnect = false;
        XREApplicationData applicationData = receiver.getApplicationData();
        if (!ReceiverUtil.isEmpty(applicationData.getSessionGUID())) {
            reconnect = true;
        }

        StringBuilder sb = new StringBuilder();
        sb.append("{\"source\":1,\"handler\":1,\"event\":0,\"phase\":\"STANDARD\",\"timestamp\":");
        sb.append(new Date().getTime());
        sb.append(",\"params\":{\"reconnect\":").append(reconnect);
        ApplicationConnectionData connectionData = receiver.getApplicationConnectionData();
        sb.append(",\"applicationName\":\"").append(connectionData.getApplicationName());
        sb.append("\",\"appParams\":{},\"deviceCaps\":{\"receiverVersion\":\"").append(
                getString(connectionData.getDeviceCaps().getReceiverVersion()));
        sb.append("\",\"platform\":\"").append(getString(connectionData.getDeviceCaps().getPlatform()));
        sb.append("\",\"platformVersion\":\"").append(getString(connectionData.getDeviceCaps().getPlatformVersion()));
        sb.append("\",\"mimeTypes\":").append(arrayToString(connectionData.getDeviceCaps().getMimeTypes()));
        sb.append(",\"nativeDimensions\":[").append(connectionData.getDeviceCaps().getNativeDimensions()[0])
                .append(",").append(connectionData.getDeviceCaps().getNativeDimensions()[1]).append("]},");
        sb.append("\"minimumVersion\":\"").append(getString(connectionData.getMinimumVersion())).append("\"");
        if (connectionData.getAuthenticationToken() != null) {
            sb.append(",\"authenticationToken\":\"").append(connectionData.getAuthenticationToken()).append("\"");
        }
        if (reconnect) {
            sb.append(",\"sessionGUID\":\"").append(applicationData.getSessionGUID()).append("\"");
        }
        sb.append(",\"currentCommandIndex\":").append(applicationData.getCurrentCommandIndex());
        sb.append("},\"name\":\"onConnect\"}");
        return sb.toString();
    }

    /**
     * Gets a string of an object.
     * 
     * @param object
     *            the <code>Object</code> instance
     * @return string representation of the object
     */
    private static String getString(Object object) {
        if (object == null) {
            return "";
        }
        return object.toString();
    }

    /**
     * Converts an array of <code>Object</code> instance to string representation.
     * 
     * @param array
     *            the array of <code>Object</code> instance
     * @return string representation of the array
     */
    private static String arrayToString(Object[] array) {
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        if (array != null) {
            for (int i = 0; i < array.length; i++) {
                if (i > 0) {
                    sb.append(",");
                }
                sb.append("\"").append(getString(array[i])).append("\"");
            }
        }
        sb.append("]");
        return sb.toString();
    }

    /**
     * Converts alpha value from XRE representation to Android representation.
     * 
     * @param alpha
     *            the alpha value in XRE representation
     * @return the alpha value in Android representation
     */
    public static int getNormalAlpha(double alpha) {
        return (int) (alpha * 255);
    }

    /**
     * Let current thread to sleep a specification time.
     */
    public static void animateSleep() {
        try {
            Thread.sleep(Config.ANIMATION_INTERVAL);
        } catch (InterruptedException e) {
            // ignore
        }
    }
}
